package com.fengxu.gamescript.data;

import android.content.Context;

import com.alibaba.fastjson.JSONObject;
import com.fengxu.gamescript.data.other.KeyConfData;
import com.fengxu.gamescript.data.other.Point;
import com.fengxu.gamescript.data.other.YsKeyConf;
import com.fengxu.gamescript.util.CommonUtils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import kotlin.Deprecated;

/**
 * 键位配置存储类，将配置存储到磁盘
 */
public class KeyConf {

    // 存储键位配置的json文件名
    private static final String ConfFileName = "key_conf.json";

    // 单例
    private static volatile KeyConf instance;

    /**
     * 键位配置列表
     */
    private List<KeyConfData> keyConfDataList = new ArrayList<>();

    /**
     * 当前激活/使用的键位配置
     */
    private KeyConfData activeKeyConfData;

    private KeyConf(){}

    /**
     * 读取键位配置
     * @param context 上下文对象
     * @return  配置类
     */
    public synchronized static KeyConf readKeyConf(Context context){
        if(instance != null) return instance;
        try {
            FileInputStream fileInputStream = context.openFileInput(ConfFileName);
            String json = CommonUtils.INSTANCE.readInputStream(fileInputStream);
            fileInputStream.close();
            instance = JSONObject.parseObject(json, KeyConf.class);
            return instance;
        }catch (FileNotFoundException e){
            instance = new KeyConf();
            instance.addKeyConfFromOldSetting();
            return instance;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 从老版本键位设置中获取原神键位设置
     */
    private void addKeyConfFromOldSetting(){
        YsKeyConf ysKeyConf = Conf.getConf().getYsKeyConf();
        Point[] keyPoints = ysKeyConf.getKeyPoints();
        // 将原来的键位按音从小到大排列
        // 只需要将第一排和第三排互换即可
        for (int i = 0; i < 7; i++) {
            Point point = keyPoints[i];
            keyPoints[i] = keyPoints[i + 7*2];
            keyPoints[i + 7*2] = point;
        }
        KeyConfData keyConfData = new KeyConfData();
        keyConfData.setRow(3);
        keyConfData.setColumn(7);
        keyConfData.setName("原神-系统计算或旧配置");
        keyConfData.setPoints(keyPoints);
        keyConfData.setSeries(true);
        keyConfData.setAbateHighVolume(false);
        keyConfData.setCreateTime(new Date());
        keyConfDataList.add(keyConfData);
    }

    /**
     * 保存键位信息
     * @param context 上下文对象
     */
    public synchronized static void saveConf(Context context){
        String jsonString = JSONObject.toJSONString(instance);
        try {
            FileOutputStream fos = context.openFileOutput(ConfFileName, Context.MODE_PRIVATE);
            fos.write(jsonString.getBytes());
            fos.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public List<KeyConfData> getKeyConfDataList() {
        return keyConfDataList;
    }

    public void setKeyConfDataList(List<KeyConfData> keyConfDataList) {
        this.keyConfDataList = keyConfDataList;
    }

    public KeyConfData getActiveKeyConfData() {
        // 若存在键位配置项，并且未激活任意一项时，默认使用第一项
        if(activeKeyConfData == null && keyConfDataList.size() > 0){
            activeKeyConfData = keyConfDataList.get(0);
        }
        return activeKeyConfData;
    }

    @Deprecated(message = "若您是激活配置请使用activeConf方法,不可使用该方法激活!!!")
    public void setActiveKeyConfData(KeyConfData activeKeyConfData) {
        this.activeKeyConfData = activeKeyConfData;
    }

    /**
     * 激活一项键位配资,不存在则抛出异常
     * @param confName  配置名
     */
    public void activeConf(String confName){
        KeyConfData confData = keyConfDataList.stream()
                .filter(keyConfData -> keyConfData.getName().equals(confName))
                .findFirst().get();
        this.activeKeyConfData = confData;
        // 将激活配置放置第一位
        keyConfDataList.remove(confData);
        keyConfDataList.add(0, confData);
    }


    @Override
    public String toString() {
        return "KeyConf{" +
                "keyConfDataList=" + keyConfDataList +
                ", activeKeyConfData=" + activeKeyConfData +
                '}';
    }
}
